package pers.qianyu.module.image.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import pers.qianyu.module.core.comm.Pagination;
import pers.qianyu.module.core.domain.image.converter.LabelConverter;
import pers.qianyu.module.core.domain.image.dataobj.LabelCountDO;
import pers.qianyu.module.core.domain.image.dto.LabelDTO;
import pers.qianyu.module.core.domain.image.entity.ImageLabelPO;
import pers.qianyu.module.core.domain.image.entity.ImagePO;
import pers.qianyu.module.core.domain.image.entity.LabelPO;
import pers.qianyu.module.core.domain.image.query.LabelQuery;
import pers.qianyu.module.core.domain.image.vo.ImageVO;
import pers.qianyu.module.core.domain.image.vo.LabelVO;
import pers.qianyu.module.image.dao.ImageDao;
import pers.qianyu.module.image.dao.ImageLabelDao;
import pers.qianyu.module.image.dao.LabelDao;
import pers.qianyu.module.image.service.ImageService;
import pers.qianyu.module.image.service.LabelService;

import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author mizzle rain
 * @date 2021-04-07 11:56
 */
@Service("labelService")
public class LabelServiceImpl implements LabelService {
    @Autowired
    private LabelDao labelDao;
    @Autowired
    private ImageLabelDao imageLabelDao;
    @Autowired
    private ImageDao imageDao;
    @Autowired
    private ImageService imageService;
    @Autowired
    private LabelConverter labelConverter;

    @Override
    public Set<LabelCountDO> getAllLabels() {
        List<LabelCountDO> labelCountDOS = labelDao.findAllTagsCount();
        return new HashSet<>(labelCountDOS);
    }

    @Override
    public void insert(LabelDTO labelDTO) {
        LabelPO labelPO = new LabelPO();
        labelPO.setName(labelDTO.getName());
        Integer cnt = labelDao.selectCount(new QueryWrapper<>(labelPO));
        if (cnt > 0) {
            return;
        }
        labelDao.insert(labelPO);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteById(Long id) {
        labelDao.deleteById(id);
        QueryWrapper<ImageLabelPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("label_id", id);
        List<ImageLabelPO> imageLabelPOS = imageLabelDao.selectList(queryWrapper);
        Set<Long> imageIds = imageLabelPOS.stream()
                .map(ImageLabelPO::getImageId)
                .collect(Collectors.toSet());
        imageLabelDao.delete(queryWrapper);
        imageDao.deleteBatchIds(imageIds);
    }

    @Override
    public Pagination<ImageVO> findImagesByLabel(LabelQuery labelQuery) {
        if (Objects.isNull(labelQuery.getLabelId()) && StrUtil.isBlank(labelQuery.getLabelName())) {
            return Pagination.emptyPage(labelQuery.getPage(), labelQuery.getLimit());
        }
        LabelPO labelPO = new LabelPO();
        labelPO.setName(labelQuery.getLabelName());
        labelPO.setId(labelQuery.getLabelId());
        labelPO = labelDao.selectOne(new QueryWrapper<>(labelPO));
        Long labelId = labelPO.getId();

        ImageLabelPO imageLabelPO = new ImageLabelPO();
        imageLabelPO.setLabelId(labelId);
        List<ImageLabelPO> imageLabelPOS = imageLabelDao.selectList(new QueryWrapper<>(imageLabelPO));
        Set<Long> imageIds = imageLabelPOS.stream().map(ImageLabelPO::getImageId).collect(Collectors.toSet());

        Page<ImagePO> imagePOPage = new Page<>(labelQuery.getPage(), labelQuery.getLimit());
        QueryWrapper<ImagePO> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", imageIds);
        return imageService.queryImagePageInfo(imagePOPage, queryWrapper);
    }

    @Override
    public Pagination<LabelVO> pageQuery(LabelQuery labelQuery) {
        QueryWrapper<LabelPO> wrapper = new QueryWrapper<>();
        Page<LabelPO> page = new Page<>(labelQuery.getPage(), labelQuery.getLimit());
        if (StrUtil.isNotBlank(labelQuery.getLabelName())) {
            wrapper.like("name", labelQuery.getLabelName());
        }
        Page<LabelPO> labelPOPage = labelDao.selectPage(page, wrapper);
        if (StrUtil.isNotBlank(labelQuery.getLabelName())) {
            for (LabelPO record : labelPOPage.getRecords()) {
                String labelName = record.getName();
                String regex = String.format("(%s)", labelQuery.getLabelName());
                labelName = labelName.replaceAll(regex, "<font style='color:red;'>$1</font>");
                record.setName(labelName);
            }
        }
        return new Pagination<>(
                labelPOPage.getRecords()
                        .stream()
                        .map(labelConverter::convToVo)
                        .collect(Collectors.toList()),
                labelPOPage.getTotal(),
                labelPOPage.getSize(),
                labelPOPage.getCurrent()
        );
    }
}
